/*
 * TocGenerator.java
 *
 *  created: 20.8.2011
 *  charset: UTF-8
 *  license: MIT (X11) (See LICENSE file for full license)
 */
package cz.mp.k3bg.core;

import static cz.mp.k3bg.Application.EOL;
import cz.mp.k3bg.log.LoggerManager;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Locale;
import java.util.logging.Logger;

// TODO ! TOC_TITLE_LEVEL nemusí být správně ...

/**
 * Třída {@code TocGenerator} vytváří obsah ze všech zdrojových HTML souborů
 * určených v instanci {@linkplain BookFiles}.
 *
 * @author Martin Pokorný
 * @version 0.2
 */
public class TocGenerator extends Generator {

    private static final boolean DEBUG = false;
    private static final Logger logger =
            LoggerManager.getLogger(TocGenerator.class, DEBUG);
    
    /** */
    private static final int TOC_TITLE_LEVEL = 2;
    /** */
    private static final int DEFAULT_LEVEL = 3;
    /** */
    private int level = DEFAULT_LEVEL;
    
    private static final String DEFAULT_TOC_TITLE;
    static {
        if (Locale.getDefault().getLanguage().equals(
                new Locale("cs","","").getLanguage())) {
            DEFAULT_TOC_TITLE = "Obsah";
        }
        else {
            DEFAULT_TOC_TITLE = "Table of Contents";
        }
    }
    
    // -----

    /**
     *
     * @param bookFiles
     * @param metadata
     */
    public TocGenerator(BookFiles bookFiles) {
        super(bookFiles, null);
    }

//    /**
//     *
//     * @param bookFiles
//     * @param metadata
//     */
//    public TocGenerator(BookFiles bookFiles, Metadata metadata) {
//        super(bookFiles, metadata);
//    }

    // -----
    
    /**
     * 
     * @param tocLevel 
     */
    public void setLevel(int tocLevel) {
        setLevelImpl(tocLevel);
    }

    /**
     * 
     * Voláno konstruktorem.
     * 
     * @param tocLevel 
     */
    private void setLevelImpl(int tocLevel) {
        logger.config("tocLevel = " + tocLevel);
        if (tocLevel < 1 || tocLevel > 6) {
            throw new IllegalArgumentException("tocLevel: 1-6");
        }
        this.level = tocLevel;
    }
        
    /**
     * 
     * @return 
     */
    public int getLevel() {
        return level;
    }
    
    /**
     * 
     * @throws IOException 
     */
    @Override
    public void generate() throws IOException {
        logger.info("");
        
        if (bookFiles.getToc() == null) {
            throw new IllegalStateException("toc=null");
        }
        
        BufferedWriter writer = bookFiles.getToc().getBufferedWriter();
        
        HtmlHeaderBuilder headerBuilder = new HtmlHeaderBuilder();
        headerBuilder.setCharsetName(bookFiles.getToc().getCharsetName());       
        headerBuilder.setStylesheetFilePathName(
                bookFiles.getBaseStyle().getCorrectedPath(
                    bookFiles.getWorkingDirPath()));
        
        // sestavení souboru :
        writer.write(headerBuilder.createHtmlHeader());
        writer.flush();        
        
        String tocTitle = bookFiles.getToc().getTitleInToc() == null ?
                DEFAULT_TOC_TITLE : bookFiles.getToc().getTitleInToc();
        if (! tocTitle.trim().isEmpty()) {
            writer.write(createTocTitle(tocTitle));
            writer.flush();
        }

        
        
        if (bookFiles.getColophon() != null) {
            logger.finer("(colophon)");
            writer.write(EOL);
            writer.write("<!--");
            writer.write(EOL);
            writer.write(createTocItem(
                    bookFiles.getColophon(),
                    TOC_TITLE_LEVEL));
            writer.write("-->");
            writer.write(EOL);
            writer.write(EOL);
            writer.flush();           
        }
        
        if (bookFiles.getLoi() != null) {
            logger.fine("add:  (List Of Illustrations)");
            writer.write(EOL);
            writer.write(createTocItem(
                    bookFiles.getLoi(),
                    TOC_TITLE_LEVEL));
            writer.flush();           
        }
        
        // TOC
        if (bookFiles.getLoi() != null) {
            writer.write(EOL);
            writer.write("<!--");
            writer.write(EOL);            
        }
        logger.finer("(toc)");
        writer.write(createTocItem(
                tocTitle, 
                bookFiles.getToc().getCorrectedPath(
                    bookFiles.getWorkingDirPath()),
                TOC_TITLE_LEVEL));
        if (bookFiles.getLoi() != null) {
            writer.write("-->");
            writer.write(EOL);
            writer.write(EOL);
        }
        writer.flush();
        
        // --
        for (HtmlFile srcFile : bookFiles.getSrcHtmlFiles()) {
            ChaptersWithAnchorFinder af = new ChaptersWithAnchorFinder(srcFile);
            af.setLevel(level);
            af.find();
                    
            for (ChapterWithAnchor ca : af.getChaptersWithAnchor()) {
                logger.fine("add:  " + ca.toString());
                writer.write(createTocItem(srcFile, ca));
                writer.flush();
            }
        }
        
        writer.write(headerBuilder.createHtmlFooter());
        writer.flush();
        
        writer.close();
        
        bookFiles.getToc().initExisting();
        
        logger.fine("(finished!)");
    }
    
    /**
     * 
     * @param ach
     * @return 
     */
    private String createTocItem(HtmlFile srcFile, ChapterWithAnchor ach) {
        if (ach == null) {
            throw new IllegalArgumentException("ach=null");
        }
        if (srcFile == null) {
            throw new IllegalArgumentException("srcFile=null");
        }        
        return createTocItem(
                ach.getChapterName(), 
                srcFile.getCorrectedPath(bookFiles.getWorkingDirPath())
                    + "#" + ach.getAnchorName(), 
                ach.getLevel());
    }
    
    /**
     * 
     * @param ach
     * @return 
     */
    private String createTocItem(HtmlFile srcFile, int level) {
        if (srcFile == null) {
            throw new IllegalArgumentException("srcFile=null");
        }
        return createTocItem(
                srcFile.getTitleInToc(), 
                srcFile.getCorrectedPath(bookFiles.getWorkingDirPath()), 
                level);
    }    
    

    /**
     * 
     * @param name
     * @param href
     * @return 
     */
    private String createTocItem(String name, String href, int level) {
        StringBuilder sb = new StringBuilder(128);
        sb.append("<p class=\"")
                .append(StyleClassNames.TOC_LEVEL_BASE.getRealName())
                .append(level)
                .append("\">");
        sb.append("<a href=\"")
                .append(href).append("\">");
        sb.append(name);
        sb.append("</a></p>");
        sb.append(EOL).append(EOL);
        return sb.toString();
    }

    /**
     * 
     * @return 
     */
    private String createTocTitle(String tocTitle) {
        StringBuilder sb = new StringBuilder(64);
        sb.append("<h").append(TOC_TITLE_LEVEL).append(" class=\"")
                .append(StyleClassNames.TOC_TITLE.getRealName()).append("\">")
                .append(tocTitle)
                .append("</h").append(TOC_TITLE_LEVEL).append(">");
        sb.append(EOL).append(EOL);
        return sb.toString();
    }
    
}   // TocGenerator
